import Configs from "@/config";
import { SquareGroup } from "./SquareGroup";
import { createTeris } from "./Teris";
import { TerisRule } from "./TerisRule";
import { EGameStatus, EMoveDirection, IGameViewer } from "./types";

export class Game {
  /** 游戏状态 */
  private _gameStatus: EGameStatus = EGameStatus.init;
  /** 当前控制的方块 */
  private _curTeris?: SquareGroup;
  /** 下一个方块 */
  private _nextTeris: SquareGroup = createTeris({ x: 0, y: 0 });
  /** 自由下落的计时器 */
  private _timer?: any;
  /** 下落时间间隔 */
  private _duration: number = 2000;
  get gameStatus() {
    return this._gameStatus;
  }
  get curTeris() {
    return this._curTeris;
  }
  get nextTeris() {
    return this._nextTeris;
  }
  constructor(private _viewer: IGameViewer) {
    this.resetCenterPoint(Configs.nextPanelWidth, this._nextTeris);
    this._viewer.showNext(this._nextTeris);
  }

  /** 开始游戏 */
  start() {
    if (this._gameStatus === EGameStatus.playing) {
      return;
    }
    this._gameStatus = EGameStatus.playing;
    if (!this._curTeris) {
      this.switchTeris();
    }
    this.autoDrop();
  }

  /** 游戏暂停 */
  pause() {
    if (this._gameStatus === EGameStatus.playing) {
      this._gameStatus = EGameStatus.pause;
      clearInterval(this._timer);
      this._timer = undefined;
    }
  }
  private switchTeris() {
    this._curTeris = this._nextTeris;
    this.resetCenterPoint(Configs.panelWidth, this._curTeris);
    this._nextTeris = createTeris({ x: 0, y: 0 });
    this.resetCenterPoint(Configs.nextPanelWidth, this._nextTeris);
    this._viewer.switch(this._curTeris);
    this._viewer.showNext(this._nextTeris);
  }
  /** 方块自由下落 */
  private autoDrop() {
    if (this._timer !== undefined) return;
    if (this._gameStatus !== EGameStatus.playing) return;
    if (!this._curTeris) return;

    this._timer = setInterval(() => {
      if (!this._curTeris) return;
      TerisRule.move(this._curTeris, EMoveDirection.down);
    }, this._duration);
  }

  /**
   * 设置中心点坐标
   * @param width 下个方块区域的大小
   */
  private resetCenterPoint(width: number, teris: SquareGroup) {
    const x = Math.floor(width / 2);
    const y = 0;
    teris.centerPointMove({ x, y });
    while (teris.squares.some((sq) => sq.point.y < 0)) {
      teris.centerPointMove({
        x: teris.centerPoint.x,
        y: teris.centerPoint.y + 1,
      });
    }
  }
}
